<?php

namespace Common\Logic;
use Home\Logic\UsersLogic;

/**
 * 抽奖
 */
class LotteryLogic
{
    const CONFIG_TABLE = "lottery_config";
    const MEMBER_TABLE = "users";
    const RECORD_TABLE = "lottery_record";
    const PRIZE_TABLE = "lottery_prize";
    const COUPON_TABLE = "Coupon";
    const COUPON_LIST_TABLE = "CouponList";
    const COUPON_PRICE = "users";

    const COUPON_PRIZE_TYPE = 6;//可以兑换积分的奖品类型

    const MONEY_PRIZE_TYPE = 5;//可以兑换余额的奖品类型

    const GOODS_PRIZE_TYPE = 7;//可以兑换商品的奖品类型

    const CHECK_TIME = FALSE; //检查抽奖开始结束时间

    const show_prize_num = 8;//展示奖品数量

    const show_lucker_num = 6;//展示获奖人数量

    const auto_sort = TRUE;//奖品自动排序

    const auto_create_prize = TRUE;//自动补齐不足的部分的奖品

    const auto_create_roboot = TRUE;//自动补齐创建最近的获奖假数据

    const lucker_roboot = [
    	["nickname" => "阿凡提哥哥","mobile"=>"187****2376"],
    	["nickname" => "呵呵~~","mobile"=>"135****7560"],
    	["nickname" => "大石岗","mobile"=>"130****8834"],
    	["nickname" => "w我是谁","mobile"=>"150****2983"],
    	["nickname" => "京师大镖客","mobile"=>"137****2030"],
    	["nickname" => "awon","mobile"=>"177****2397"],
    	["nickname" => "黑列巴","mobile"=>"186****2399"],
    	["nickname" => "费勒","mobile"=>"182****3929"],
    ];

    /**
    * 获取奖品信息
    */ 
    public static function getPrizeList()
    {
    	$list = M(self::PRIZE_TABLE)->where([
    		"prize_status" => 1,
    		"prize_weight" => ["gt",0]
    	])->field('prize_id,prize_name,prize_num,prize_img,prize_sort,prize_status')->order( 'prize_sort asc' )->limit( self::show_prize_num )->select();
    	$dirt = self::show_prize_num - count($list);

    	if( self::auto_create_prize && $dirt > 0  )
    	{
    		for($i=0;$i<$dirt;$i++)
			{
				$list[] = [
					"prize_id" => 0,
					"prize_name" => "未中奖",
					"prize_num" => 10,
					"prize_img" => 'Public/upload/lottery/2018-09-10/weizhongjiang.png',
                    // "prize_img" => '',
					"prize_sort" => 0,
					"prize_status" => 1
				];
			}
    	}

    	if( self::auto_sort )
    	{
    		shuffle($list);
    	}

    	return $list;
    }

    /**
    * 获取最近中奖的信息
    */ 
    public static function getLucker()
    {
    	$cache = S("LOTTERY_LUCKERS");

    	if( $cache )
    		return $cache;

    	$records = M( self::RECORD_TABLE )->where("prize_id > 0")->limit(self::show_lucker_num)->field("id,user_id,prize_id")->order("create_time desc")->select();
 		
 		$Member = M(self::MEMBER_TABLE);
 		$Prize = M(self::PRIZE_TABLE);

  		if( $records )
  		{	
  			foreach ($records as $key => &$val) 
  			{
  				$prize = $Prize->where(["prize_id"=>$val['prize_id']])->cache(300)->field("prize_id,prize_name")->find();
  				$val['prize_name'] = $prize['prize_name'];
  				$user = $Member->where([
  					"user_id" => $val['user_id']
  				])->field("user_id,head_pic,mobile,nickname")->cache(300)->find();
  				$user['mobile'] = remove_sens($user['mobile'],3,4);
  				$val['info'] = $user;
  			}
  			unset($key);
  			unset($val);
  		}

    	$dirt = self::show_lucker_num - count($records);

    	if( self::auto_create_roboot && $dirt > 0 )
    	{
    		$prizes = $Prize->field("prize_id,prize_name")->limit(self::show_lucker_num)->select();

    		for($i=0;$i<$dirt;$i++)
			{

				$user = self::lucker_roboot[$i];
				$records[] = [
					"id" => 0,
					"user_id" => 0,
					"prize_id" => 0,
					"prize_name" => $prizes[ array_rand($prizes) ]['prize_name'],
					"info" => [
						"user_id" => 0,
						"nickname" => $user['nickname'],
						"mobile" => $user['mobile'],
						"head_pic" => ''
					]
				];
			}
    	}

    	S("LOTTERY_LUCKERS",$records,60);
        // var_dump($records);
    	return $records;
    }


    /**
    * 进行抽奖
    * @param $userId
    * @return mix
    */ 
    public static function lotteryDraw($userId = 0)
    {
    	if( !$userId )
    		throw new \Exception('参数错误',401);

    	if( self::CHECK_TIME )
    	{
    		if( !self::checkLotteryTime() )
    			throw new \Exception('抽奖活动未开始', 402);
    	}

    	/* 验证用户是否满足抽奖条件 */
        $lotteryConsume = self::getConfig("lotteryConsume");
        
        $user = M('users')->where([
            "user_id" => $userId
        ])->field("user_id,pay_points")->find();

        $need_reduce_score = intval($lotteryConsume['value']);
        // var_dump($user);die;
        // var_dump("应扣除积分",$need_reduce_score);die;
        if( $need_reduce_score > $user['pay_points'] )
            throw new \Exception(C('POINT_NAME').'不足,无法抽奖', 403);

        if( !self::checkUserLotteryNum($userId) )
        	throw new \Exception('今日抽奖次数到达上限', 404);

        M()->startTrans();

        #扣积分
        if( $need_reduce_score > 0 )
        {
            $reduce_score = accountLog($userId,0,-1*$need_reduce_score,"参加抽奖",0);
            if( !$reduce_score || !$reduce_score['is_success'] )
            {
                M()->rollback();
                throw new \Exception(C('POINT_NAME').'扣除失败',-3);//未中奖
            }
        }
        
        $prizeInfo = self::getPrizeId();
        if(!$prizeInfo)
        {
        	$data['create_time'] = time();
	        $data['prize_id'] = 0;
            $data['user_id'] = $userId;
            
            $record = M(self::RECORD_TABLE)-> add($data);

	        if($record){
                M()->commit();
	        	throw new \Exception('unPrize',0);//未中奖
	        }else{
                M()->rollback();
	        	throw new \Exception('系统出错',-1);
            }
        }

        #是否已经发放标记
        $is_dispatch = 0;

        /* 奖品需要验证数量，抽奖完成奖品数量-1 */
        if($prizeInfo['check_num'] == 1){
            $update = self::updatePrizeNum($prizeInfo['prize_id']);

            if($update === FALSE)
            {
            	M()->rollback();
        		throw new \Exception('系统出错',-2);//未中奖
            }
        }

        #如果抽到积分或者奖金要加上去，#类型不对不发放
        if( $prizeInfo['category_id'] == self::COUPON_PRIZE_TYPE || $prizeInfo['category_id'] == self::MONEY_PRIZE_TYPE )
        {
            try{
                $update3 = self::dispatchPrize($userId,$prizeInfo);
            }catch(\Exception $e)
            {
                M()->rollback();
                throw new \Exception($e->getMessage(),-4);//未中奖
            }
        	
        	if( !$update3 )
	        {
	        	M()->rollback();
	    		throw new \Exception('系统出错',-41);//未中奖
            }
            
            #记录改为发放成功
            $is_dispatch = 1;
        }

        /* 添加抽奖记录 */
        $data['create_time'] = time();
        $data['prize_id'] = $prizeInfo['prize_id'];
        $data['user_id'] = $userId;
        $data['grant'] = $is_dispatch;

        $lotteryRecord = M(self::RECORD_TABLE);
        $insert_id = $lotteryRecord -> add($data);

        if( !$insert_id )
        {
        	M()->rollback();
        	throw new \Exception('系统出错',-1);//未中奖
        }

        M()->commit();
        return $prizeInfo;

    }
    /**发放奖品***/
    public static function dispatchPrize($userId,$prizeInfo = [])
    {
    	if(!$userId || empty($prizeInfo) )
            throw new \Exception('参数错误', -1);
            
        if( $prizeInfo['category_id'] != self::COUPON_PRIZE_TYPE && $prizeInfo['category_id'] != self::MONEY_PRIZE_TYPE )
        {
            throw new \Exception('该类型奖品无法发放', -1);
        }

        // 积分和余额的面额
    	if($prizeInfo['coupon_id'] == 0)
            throw new \Exception('参数错误', -2);

    	#发放        
        if( $prizeInfo['category_id'] != self::COUPON_PRIZE_TYPE  )
        {
            $add_score = accountLog($userId,0,$prizeInfo['coupon_id'],"抽奖获得");
        }elseif( $prizeInfo['category_id'] != self::MONEY_PRIZE_TYPE )
        {
            $add_score = accountLog($userId,$prizeInfo['coupon_id'],0,"抽奖获得");
        }        

        if( !$add_score || !$add_score['is_success'] )
            $add_score = false;
        
        return true;

    	// $data = [
    	// 	"cid" => $coupon['id'],
    	// 	"type" => 4,
    	// 	"uid" => $userId,
    	// 	"order_id" => 0,
    	// 	"use_time" => 0,
    	// 	"code" => "",
    	// 	"send_time" => time(),
        // ];
        

        // $addrec = M(self::COUPON_LIST_TABLE)->add($data);

        // if(FALSE === $update || !$add_score || !$addrec )
    	// {
    	// 	throw new \Exception('Dispatch Failed', -1);
        // }

    	// return true;

    }

    /**校验时间**/ 
    public static function checkLotteryTime()
    {
        $nowTime = time();
        /* 获取抽奖配置限制 */
        $startTime = self::getConfig("lotteryStartTime");
        $endTime = self::getConfig("lotteryEndTime");
       
        if($nowTime < $startTime['value'] || $nowTime > $endTime['value']){
            return false;
        }else{
            return true;
        }
    }

    /** 
    * 验证用户抽奖条件
    * @param $userId 
    * @param 满足时返回需要扣除的积分数 否则 false
    */
    protected static function checkUserLotteryStatus($userId)
    {
        /* 获取抽奖配置限制 */
        $lotteryConsume = self::getConfig("lotteryConsume");
        /* 获取用户优惠券总额 */
        $couponPrice = M(self::MEMBER_TABLE) -> field('pay_points') -> where("`user_id` = ".$userId) -> find();
        return ($couponPrice['pay_points'] < $lotteryConsume['value'] ? false : $lotteryConsume['value']);
    }

    /* 验证用户抽奖次数 */
    protected static function checkUserLotteryNum($userId)
    {
        /* 获取抽奖配置次数 */
        $lotteryNum = self::getConfig("lotteryNum");
        /* 获取用户抽奖次数 */
        $t = time();
        $start_time = mktime(0,0,0,date("m",$t),date("d",$t),date("Y",$t));  //当天开始时间
        $end_time = mktime(23,59,59,date("m",$t),date("d",$t),date("Y",$t)); //当天结束时间

        $where['user_id'] = $userId;
        $where['create_time'] = ['gt',$start_time];
        $where['create_time'] = ['lt',$end_time];
        $userNum = M(self::RECORD_TABLE) -> where($where) -> count();
        return $lotteryNum['value'] <= $userNum ? false : true;
    }

     /* 扣除优惠券总额 */
    protected static function deductCouponPrice($userId)
    {
        /* 获取抽奖配置限制 */
        $lotteryConsume = self::getConfig("lotteryConsume");
        $lotteryConsume =  $lotteryConsume ? $lotteryConsume['value'] : 10;
        /* 获取用户所有优惠券 */
        $where['uid'] = $userId;
        $where['use_time'] = 0;
        // $where['status'] = 1;
        $couponList = M('coupon_list')
                    -> alias("cl")
                    -> join('ln_coupon as c on c.id=cl.cid')
                    -> field('c.money,cl.id')
                    -> where($where)
                    -> order('c.use_end_time asc,c.money asc')
                    -> select();
        if( !$couponList )
        	throw new \Exception('优惠券余额不足', -1);

        $i = 0;
        $price = 0;
        $data = [];
        while ($price < $lotteryConsume && $i < count($couponList) ){
            $price = self::mathAdd($price,$couponList[$i]['money']);
            array_push($data,$couponList[$i]['id']);
            unset($couponList[$i]);
            $i++;
        }

        if( $price < $lotteryConsume )
        	throw new \Exception('优惠券余额不足', -2);

        $str = implode(',',$data);
        $couponTotalPrice = array_sum(array_column($couponList,'money'));
        /* 修改用户优惠劵总价 */
        $where['user_id'] = $userId;
        $map['coupon_price']=$couponTotalPrice;
        $lotteryPrize = M(self::MEMBER_TABLE)
            -> where($where)
            ->save($map);
        if( $lotteryPrize === FALSE )
        	return FALSE;
        /* 修改用户优惠券状态 */
        // var_dump($str);
        return  M(self::COUPON_LIST_TABLE)
                        -> where([
                            "id" => ["IN",$str]
                        ])-> save(['use_time' => time()]);
    }

    /* 奖品数量-1 */
    protected static function updatePrizeNum($prize_id)
    {
         return M(self::PRIZE_TABLE)
            -> where('prize_id='.$prize_id)
            -> setDec('prize_num');
    }

    /* 随机抽奖id */
    protected static function getPrizeId()
    {
        $lotteryPrize = M(self::PRIZE_TABLE)
        				->where([
        					"prize_status" => 1,
    						"prize_weight" => ["gt",0]
        				])
                        -> field('prize_id,prize_weight,prize_name,prize_img,prize_num,check_num,coupon_id,category_id')
                        -> select();
        //下标存储数组100个下表，0-7 按概率分配对应的数量
        $indexArr = array();
        for($i=0;$i<sizeof($lotteryPrize);$i++){
            for($j=0;$j<$lotteryPrize[$i]['prize_weight'];$j++){
                //index 追加到数组indexArr
                array_push($indexArr, $i);
            }
        }
        #补齐未中奖的部分
        $dirt = 100 - count($indexArr);

        if($dirt > 0)
        {
        	$unPrizeIndex = count( $lotteryPrize );
        	for($i = 0;$i < $dirt;$i++)
        	{
        		array_push($indexArr, $unPrizeIndex);
        	}
        }

        //数组乱序
        shuffle($indexArr);
        //从下标数组中随机取一个下标作为中奖下标，$rand_index 是$indexArr的随机元素的下标（0-99）
        $rand_index = array_rand($indexArr,1);


        //获取中奖信息
        $prize_index = $indexArr[$rand_index];
        if(!isset($lotteryPrize[$prize_index]))
        {
 			return FALSE;
        }

        $prizeInfo = $lotteryPrize[$prize_index];
        $data['prize_id'] = $prizeInfo['prize_id'];
        $data['prize_name'] = $prizeInfo['prize_name'];
        $data['prize_img'] = $prizeInfo['prize_img'];
        $data['prize_num'] = $prizeInfo['prize_num'];
        $data['check_num'] = $prizeInfo['check_num'];
        $data['category_id'] = $prizeInfo['category_id'];
        $data['coupon_id'] = $prizeInfo['coupon_id'];

        if($data['check_num'] == 1 && $data['prize_num'] == 0){
            return false;
        }else{
            return $data;
        }
    }

    /* 获取用户抽奖次数信息 */
    public static function getUserLuckCount($userId)
    {	
    	$res = [
    		"total" => 0,
    		"remind" => 0,
    		"used" => 0
    	];

    	if(!$userId)
    		return $res;

    	if( self::CHECK_TIME )
    	{
    		if(!self::checkLotteryTime())
    			return $res;
    	}

    	$count = M(self::RECORD_TABLE)->where([
			"user_id" => $userId,
			"create_time" => ["gt",strtotime(date('Y-m-d'))]
		])->count();#已经抽了几次

        $pay_points = self::getPoint($userId);
		$lotteryNum = self::getConfig("lotteryNum");//能抽几次
		$lotteryNum = (int)$lotteryNum['value'];//能抽几次
		$lottery_money = self::getConfig("lotteryConsume");//每抽一次需要的积分
        $lottery_money = (int)$lottery_money['value']; 
        $conf = floor($pay_points / $lottery_money);
        if ( $lotteryNum <= $count ) {
           return [
                "total" => $lotteryNum,
                "remind" => 0,
                "used" => $count
            ];
        }
        return [
    		"total" => $lotteryNum,
    		"remind" => $lotteryNum - $count,
    		"used" => $count
    	];
    }

    /* 获取用户获奖记录 */
    public static function getUserRecord($userId,$invalid = FALSE){

        // if(!$userId)
        // 	throw new \Exception('参数错误',401);

        $model =M(self::RECORD_TABLE);
        
        $where['user_id'] =  $userId;

        if($invalid)
        {
        	$where['prize_id'] =  ["gt",0];
        }

        $count = $model->where($where)->count();
        $Page = new \Think\Page($count,10);

        $list = $model->where($where)->field('id,user_id,prize_id,create_time')->limit($Page->firstRow,$Page->listRows)->order("create_time desc")->select();

        $Prize = M(self::PRIZE_TABLE);

        foreach ($list as $k => &$val) 
        {
        	if( !$val['prize_id'] )
        	{
        		$val['prize_name'] = "未中奖";
        		$val['prize_img'] = "";
        		continue;
        	}
        	$p = $Prize->where(['id'=>$val['prize_id']])->field('prize_name,prize_img')->cache(600)->find();
        	if($p)
        	{
        		$val['prize_name'] = $p['prize_name'];
        		$val['prize_img'] = $p['prize_img'];
        	}else{
        		$val['prize_name'] = "未中奖";
        		$val['prize_img'] = "";
        	}
        }

        return [
        	"total" => $count,
        	"list" => $list,
        ];
    }

    /* 加 */
    public static function mathAdd($a,$b,$scale = '2'){
        return bcadd($a,$b,$scale);
    }

    //获取用户兑换券总额
    public static function getCoupon($userId){
        return M(self::COUPON_PRICE)->where("user_id=$userId")->field("coupon_price")->find();
    }

    //获取用户积分
    public static function getPoint($userId){
        $res =  M(self::MEMBER_TABLE)->where("user_id=$userId")->field("pay_points")->find();
        if($res) return $res['pay_points'];
        return 0;
    }

    /**
    * 获取配置信息
    */ 
    // public static function getConfig($key = "lotteryNum",$field = "value")
    public static function getConfig($key = "lotteryConsume",$field = "value")
    {
    	return M(self::CONFIG_TABLE)->where([
				'key' => $key
			])->field($field)->find();
    }



    public static function getLink($token){
        $user = M('users')->where(['token'=>$token])->find();
        if ($user){
            if($user['is_distribut'] == 1){
                $model = new UsersLogic();
                $share_link = $model->getShareLink($user);
            }else{
                $model = new UsersLogic();
                $share_link = $model->getShareLink($user);
            }
        }

        return $share_link;
    }

}
